package com.muyu.common.core.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.Assert;

import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.WeekFields;
import java.util.*;
import java.util.stream.Stream;

import static java.util.stream.Collectors.toList;

/**
 * 日期工具类
 *
 * @author yhq [unicorn668@163.com] 创建时间：2012-11-2 上午11:18:44
 * @version V1.0
 */
public final class DateUtil extends org.apache.commons.lang3.time.DateUtils{
    private static Logger logger = LoggerFactory.getLogger(DateUtil.class);
    /**
     * 默认的年月日
     */
    public static final String defaultPattern = "yyyy-MM-dd";
    public static final String CN_PATTERN = "yyyy年MM月dd日";
    public static final String DATE_DAY = "yyyy-MM-dd";
    public static final String YEAR_MONTH = "yyyy-MM";
    public static final String DATE_DAY_NOLINE = "yyyyMMdd";
    public final static String DATETIME_Filename = "yyyyMMddHHmmssSSS";
    private final static SimpleDateFormat sdfTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    private final static String ZONETIME = "yyyy-MM-dd'T'HH:mm:ss'+08:00'";
    public final static String DATETIME = "yyyy-MM-dd HH:mm:ss";
    public final static String DATETIME_STR = "yyyyMMddHHmmss";
    public final static String DATETIME_SLASH = "yyyy/MM/dd HH:mm:ss";
    public final static String DATEHM_SLASH = "yyyy/MM/dd HH:mm";
    /**
     * hour12HMSPattern年月日 时分秒 12小时制
     */
    public static final String hour12HMSPattern = "yyyy-MM-dd hh:mm:ss";
    public final static Date currentDate() {
        return new Date();
    }
    public static String getCurrentTime() {
        return sdfTime.format(new Date());
    }

    private static String[] parsePatterns = {
            "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
            "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
            "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};

    /**
     * hour12HMPattern年月日 时分 12小时制
     */
    public static final String hour12HMPattern = "yyyy-MM-dd hh:mm";

    /**
     * hour12HPattern年月日 时 12小时制
     */
    public static final String hour12HPattern = "yyyy-MM-dd hh";

    /**
     * hour24HMSPattern年月日 时分秒 24小时制
     */
    public static final String hour24HMSPattern = "yyyy-MM-dd HH:mm:ss";

    public static final String localPattern = "yyyy年MM月dd日  HH:mm:ss";

    /**
     * hour24HMPattern年月日 时分 24小时制
     */
    public static final String hour24HMPattern = "yyyy-MM-dd HH:mm";

    /**
     * hour24HPattern年月日 时 24小时制
     */
    public static final String hour24HPattern = "yyyy-MM-dd HH";

    /**
     * hour24HPattern年月日 时 24小时制
     */
    public static final String hour24Pattern = "yyyyMMddHHmmss";

    private static final SimpleDateFormat df = new SimpleDateFormat(hour24HMSPattern);

    public final static Date s2d(String dateStr, String mask) {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat(mask);
            return sdf.parse(dateStr);
        } catch (Exception e) {
            return null;
        }
    }

    //两个时间小时差
    public static int getDateHoursDifference(Date beforeDate, Date afterDate) {
        long difference = afterDate.getTime() - beforeDate.getTime();
        return (int) difference/1000/60/60;
    }

    //一个时期往前/后推N小时
    public static Date dateRoll(Date date, int n) {
        // 获取Calendar对象并以传进来的时间为准
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        // 将现在的时间滚动固定时长,转换为Date类型赋值
        calendar.add(Calendar.HOUR, n);
        // 转换为Date类型再赋值
        date = calendar.getTime();
        return date;
    }

    //一个时期往前/后推N分钟
    public static Date minuteRoll(Date date, int n) {
        // 获取Calendar对象并以传进来的时间为准
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        // 将现在的时间滚动固定时长,转换为Date类型赋值
        calendar.add(Calendar.MINUTE, n);
        // 转换为Date类型再赋值
        date = calendar.getTime();
        return date;
    }

    /**
     * 计算时间差，  例如返回  2天1小时4分20秒
     *
     * @param startDate 开始时间
     * @param endDate   例如返回  2天1小时4分20秒 的字符串
     * @return String
     */
    public static String daysBetween(Date startDate, Date endDate) {
        float d = endDate.getTime() - startDate.getTime();
        float dd = d / 86400000f;
        int ddd = (int) dd;

        float hh = (dd - ddd) * 24;
        int hhh = (int) hh;

        float mm = (hh - hhh) * 60;
        int mmm = (int) mm;

        float ss = (mm - mmm) * 60;
        int sss = (int) ss;
        return ddd + "天" + hhh + "小时" + mmm + "分" + sss + "秒";
    }
    public final static String d2s(Date d, String mask) {

        SimpleDateFormat sdf = new SimpleDateFormat(mask);
        String rString = sdf.format(d);

        return rString;
    }
    public static String formatDate(Date date) {
        return df.format(date);
    }

    public static String formatDate(Date date, String formatStr) {
        if (date == null) {
            return null;
        } else {
            return new SimpleDateFormat(formatStr).format(date);
        }
    }

    public static Date getAddDate(Date date, int addNum) {
        Calendar cld = Calendar.getInstance();
        cld.setTime(date);
        cld.add(Calendar.DATE, addNum);
        return cld.getTime();
    }

    /**
     * 返回预设Format的当前日期字符串
     */
    public static String getToday() {
        Date today = new Date();
        return format(today);
    }

    public static String getYestoday() {
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(new Date());
        cal1.add(Calendar.DATE, -1);
        return format(cal1.getTime());
    }

    public static String getTheDayBeforeYestoday() {
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(new Date());
        cal1.add(Calendar.DATE, -2);
        return format(cal1.getTime());
    }

    public static String getPreviousDay3() {
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(new Date());
        cal1.add(Calendar.DATE, -3);
        return format(cal1.getTime());
    }

    public static String getPreviousDay4() {
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(new Date());
        cal1.add(Calendar.DATE, -4);
        return format(cal1.getTime());
    }

    /**
     * 取得距离今天N天的时间
     *
     * @param n       N：今天以后N天;-N今天以前N天
     * @param pattern 指定格式
     * @return
     * @create 2013-11-5 下午10:14:17 haoqj
     * @history
     */
    public static String getOneDay(int n, String pattern) {
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(new Date());
        cal1.add(Calendar.DATE, n);
        return format(cal1.getTime(), pattern);
    }

    /**
     * 取得距离今天N天的时间(YYYY-MM-DD)
     *
     * @param n N：今天以后;-N今天以前N天
     * @return
     * @create 2013-11-5 下午10:14:17 haoqj
     * @history
     */
    public static String getOneDay(int n) {
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(new Date());
        cal1.add(Calendar.DATE, n);
        return format(cal1.getTime(), defaultPattern);
    }

    /**
     * 用预设Format格式化Date成字符串
     */
    public static String format(Date date) {
        return format(date, defaultPattern);
    }

    public static String getDate() {
        return format(new Date(), defaultPattern);
    }

    /**
     * 使用参数Format格式化Date成字符串
     */
    public static String format(Date date, String pattern) {
        String returnValue = "";

        if (date != null) {
            SimpleDateFormat df = new SimpleDateFormat(pattern);
            returnValue = df.format(date);
        }

        return (returnValue);
    }

    /**
     * 使用预设格式将字符串转为Date
     */
    public static Date parse(String strDate) {
        return parse(strDate, defaultPattern);
    }

    /**
     * 使用参数Format将字符串转为Date
     *
     * @param strDate
     * @param pattern 字符、 格式参考<code>DateUtil 的静态常量</code>
     * @return Date
     * @throws ParseException
     */
    public static Date parse(String strDate, String pattern) {
        try {
            if (strDate != null && !"".equals(strDate)) {
                SimpleDateFormat df = new SimpleDateFormat(pattern);
                return df.parse(strDate);
            }
        } catch (Exception ex) {
            logger.info(ex.getMessage(), ex);
        }
        return null;
    }

    public static String formatDateTime(Date date) {
        SimpleDateFormat outFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return outFormat.format(date);
    }

    @SuppressWarnings("static-access")
    public static String getEndOfMonth(String year, String month) {
        Calendar cal = Calendar.getInstance();
        cal.set(cal.YEAR, Integer.parseInt(year));
        cal.set(cal.MONTH, Integer.parseInt(month) - 1);
        return cal.getActualMaximum(cal.DAY_OF_MONTH) + "";
    }

    public static String addDays(String sdate, int n) throws ParseException {
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(parse(sdate, defaultPattern));
        cal1.add(Calendar.DATE, n);
        return format(cal1.getTime());

    }

    public static String getFirstOfMonth() throws ParseException {
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(new Date());
        cal1.set(5, 1);
        return format(cal1.getTime());

    }

    public static String getFirstOfMonth(String sDate) throws ParseException {
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(parse(sDate, defaultPattern));
        cal1.set(5, 1);
        return format(cal1.getTime());

    }

    /**
     * 获取年
     *
     * @param sdate
     * @return String
     */
    public static String getYear(String sdate) {
        String[] date = sdate.split("-");
        return date[0];
    }

    /**
     * 获取月
     *
     * @param sdate
     * @return String
     */
    public static String getMonth(String sdate) {
        String[] date = sdate.split("-");
        return date[1];
    }

    public static String getCurrentYear() {
        Calendar cale = Calendar.getInstance();
        return Integer.toString(cale.get(Calendar.YEAR));
    }

    public static String getCurrentMonth() {
        Calendar cale = Calendar.getInstance();
        int month = cale.get(Calendar.MONTH);
        month++;
        String sMonth = Integer.toString(month);
        if (month < 10)
            sMonth = "0" + month;
        return sMonth;
    }

    public static String getCurrentWeekOfYear() {
        Calendar cale = Calendar.getInstance();
        return String.valueOf(cale.get(Calendar.YEAR) * 100 + cale.get(Calendar.WEEK_OF_YEAR));
    }

    /**
     * 获取天
     *
     * @param sdate
     * @return String
     */
    public static String getDay(String sdate) {
        String[] date = sdate.split("-");
        return date[2];
    }

    public static String getFullDate(String date) {
        if (date != null && date.length() == 1)
            return "0" + date;
        return date;
    }

    public static String getSimpleDateString(String sdate) {
        return sdate.replace("-", "");
    }

    //把日期从字符串转成日期型
    public static Date convertStringToDate(String pattern, String strDate)
            throws ParseException {
        Date aDate = null;
        aDate = parse(strDate, pattern);
        return aDate;
    }

    //根据指定格式得到当前日期的字符串
    public static String getTodayDate(String aMask) {
        Date date = new Date();
        return getDateTime(aMask, date);
    }

    //根据指定格式得到指定日期的字符串
    public static String getDateTime(String aMask, Date aDate) {
        SimpleDateFormat df = null;
        String returnValue = "";
        df = new SimpleDateFormat(aMask);
        returnValue = df.format(aDate);
        return (returnValue);
    }

    /**
     * 处理日期格式转化
     *
     * @param date 日期对象
     * @return 日期的字符串格式
     */
    public static String dateFormat(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.get(Calendar.HOUR_OF_DAY);
        String pattern = "yyyy-MM-dd";
        if (c.get(Calendar.HOUR_OF_DAY) != 0) {
            pattern = "yyyy-MM-dd hh";
        } else if (c.get(Calendar.MINUTE) != 0) {
            pattern = "yyyy-MM-dd hh:mm";
        } else if (c.get(Calendar.SECOND) != 0) {
            pattern = "yyyy-MM-dd hh:mm:ss";
        }
        return new SimpleDateFormat(pattern).format(date);
    }


    /**
     * @param date    201306101201
     * @param pattern yyyy-MM-dd HH:mm
     * @return
     * @throws ParseException
     */
    public static Date dataFormat(String date, String pattern) throws ParseException {
        String newDate = date.substring(0, 4) + "-" + date.substring(4, 6) + "-" + date.substring(6, 8) + " " +
                date.substring(8, 10) + ":" + date.substring(10, 12) + ":" + date.substring(12, 14);
        SimpleDateFormat df = new SimpleDateFormat(pattern);
        return df.parse(newDate);
    }

    /**
     * 在一个已知时间的基础上增加指定的时间,负数表示减少
     *
     * @param year
     * @param month
     * @param date
     * @return
     */
    public static Date addDate(Date oldDate, int year, int month, int date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(oldDate);
        calendar.add(Calendar.YEAR, year);
        calendar.add(Calendar.MONTH, month);
        calendar.add(Calendar.DATE, date);
        return calendar.getTime();
    }

    /**
     * 在一个已知时间的基础上增加指定的时间,负数表示减少
     *
     * @param
     * @param year
     * @return
     */
    public static Date addYear(Date oldDate, int year) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(oldDate);
        calendar.add(Calendar.YEAR, year);
        return calendar.getTime();
    }

    /**
     * 在一个已知时间的基础上增加指定的时间,负数表示减少
     *
     * @param
     * @param month
     * @return
     */
    public static Date addMonth(Date oldDate, int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(oldDate);
        calendar.add(Calendar.MONTH, month);
        return calendar.getTime();
    }

    /**
     * 在一个已知时间的基础上增加指定的时间再加一天,负数表示减少
     * time清零
     * @param
     * @param month
     * @return
     */
    public static Date addMonthAndDay(Date oldDate, int month, int day) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(oldDate);
        calendar.add(Calendar.MONTH, month);
        calendar.add(Calendar.DATE, day);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }

    /**
     * 在一个已知时间的基础上增加指定的时间,负数表示减少
     *
     * @param
     * @param date
     * @return
     */
    public static Date addDay(Date oldDate, int date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(oldDate);
        calendar.add(Calendar.DATE, date);
        return calendar.getTime();
    }

    /**
     * 在一个已知时间的基础上增加指定的时间,负数表示减少
     *
     * @param
     * @param
     * @return
     */
    public static Date addHour(Date oldDate, int hour) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(oldDate);
        calendar.add(Calendar.HOUR, hour);
        return calendar.getTime();
    }

    /**
     * 在一个已知时间的基础上增加指定的时间,负数表示减少
     *
     * @param
     * @param minute
     * @return
     */
    public static Date addMin(Date oldDate, int minute) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(oldDate);
        calendar.add(Calendar.MINUTE, minute);
        return calendar.getTime();
    }

    /**
     * 返回两个时间相差多少秒
     *
     * @param a
     * @param b
     * @return
     */
    public static int subSecond(Date a, Date b) {
        return (int) (a.getTime()- b.getTime()) / 1000;
    }

    public static final Date getDateCurrentDate() {
        return getDateCurrentDate(defaultPattern);
    }

    public static final Date getDateCurrentDate(String pattern) {
        String strNow = getStrCurrentDate(pattern);
        return parse(strNow, pattern);
    }

    public static String getStrCurrentDate() {
        return getStrCurrentDate(defaultPattern);
    }

    public static String getStrCurrentDate(String pattern) {
        Date date = Calendar.getInstance().getTime();
        return format(date, pattern);
    }


    /**
     * 查询今天之前的日期
     *
     * @param beforeDay(把日期往后增加一天.整数往后推,负数往前移动) -1：表示昨天;1表示明天
     * @return
     */
    public static String getBeforeDate(int beforeDay) {
        Date date = new Date();
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);
        calendar.add(calendar.DATE, beforeDay);//把日期往后增加一天.整数往后推,负数往前移动
        Date endTime = calendar.getTime(); //这个时间就是日期往后推一天的结果
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        return formatter.format(endTime);
    }

    /**
     * 获得日期当月的开始日期，即2012-01-01
     *
     * @return
     * @create 2013-11-11 下午04:28:40 徐承恩
     * @history
     */
    public static Date getMonthStartTime(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        Date now = null;
        try {
            c.set(Calendar.DATE, 1);
            now = c.getTime();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return now;
    }

    /**
     * 当日期当月的结束日期，即2012-01-31
     *
     * @return
     * @create 2013-11-11 下午04:28:57 徐承恩
     * @history
     */
    public static Date getMonthEndTime(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        Date now = null;
        try {
            c.set(Calendar.DATE, 1);
            c.add(Calendar.MONTH, 1);
            c.add(Calendar.DATE, -1);
            now = c.getTime();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return now;
    }

    /**
     * 获得本月的开始日期，即2012-01-01
     *
     * @return
     * @create 2013-11-11 下午04:28:40 徐承恩
     * @history
     */
    public static Date getCurrentMonthStartTime() {
        Calendar c = Calendar.getInstance();
        Date now = null;
        try {
            c.set(Calendar.DATE, 1);
            c.set(Calendar.HOUR_OF_DAY, 0);
            c.set(Calendar.MINUTE, 0);
            c.set(Calendar.SECOND, 0);
            now = c.getTime();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return now;
    }

    /**
     * 获得上个月的开始日期，即2012-01-01
     *
     * @return
     */
    public static Date getLastMonthStartTime() {
        Calendar c = Calendar.getInstance();
        Date now = null;
        try {
            c.add(Calendar.MONTH, -1);
            c.set(Calendar.DATE, 1);
            c.set(Calendar.HOUR_OF_DAY, 0);
            c.set(Calendar.MINUTE, 0);
            c.set(Calendar.SECOND, 0);
            now = c.getTime();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return now;
    }

    /**
     * 获得上个月的结束日期，即2012-01-01
     *
     * @return
     */
    public static Date getLastMonthEndTime() {
        Calendar c = Calendar.getInstance();
        Date now = null;
        try {
            c.set(Calendar.DATE, 1);
            c.add(Calendar.DATE, -1);
            c.set(Calendar.HOUR_OF_DAY, 23);
            c.set(Calendar.MINUTE, 59);
            c.set(Calendar.SECOND, 59);
            now = c.getTime();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return now;
    }

    /**
     * 当前月的结束日期，即2012-01-31
     *
     * @return
     * @create 2013-11-11 下午04:28:57 徐承恩
     * @history
     */
    public static String getCurrentMonthEndTime() {
        Calendar c = Calendar.getInstance();
        String now = "";
        try {
            c.set(Calendar.DATE, 1);
            c.add(Calendar.MONTH, 1);
            c.add(Calendar.DATE, -1);
            now = DateUtil.format(c.getTime(), defaultPattern);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return now;
    }

    /**
     * 当前的日期，即2012-01-31
     *
     * @return
     * @create 2013-11-11 下午04:28:57 徐承恩
     * @history
     */
    public static String getCurrentDayTime() {
        Date dNow = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        return formatter.format(dNow);
    }


    /**
     * 获取当前时间后半小时的时间字符串
     *
     * @return
     * @create 2014-3-20 下午04:00:30 WUWEI
     * @history
     */
    public static String getNextHalfHourTime() {
        long crruTime = new Date().getTime();
        long halfHourTime = 30 * 60 * 1000;
        return format(new Date(crruTime + halfHourTime), hour24HMSPattern);
    }

    //当前时间的x分钟之后时间
    public static String addDateMinut(int x) throws ParseException
    // int x  当前时间几分钟后
    {
        SimpleDateFormat format = new SimpleDateFormat(hour24HMSPattern);// 24小时制
        //引号里面个格式也可以是 HH:mm:ss或者HH:mm等等，很随意的，不过在主函数调用时，要和输入的变
        //量day格式一致
        Date date = new Date();

        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.MINUTE, x);// 24小时制
        date = cal.getTime();
        cal = null;

        return format.format(date);

    }

    /**
     * 更改指定时间的"时/分/秒"
     * <br> 说明：<font color="red">如值为-1则不进行修改</font>
     *
     * @param date   原始时间
     * @param hour   时
     * @param minute 分
     * @param second 秒
     * @return
     */
    public static Date updateTime(Date date, int hour, int minute, int second) {
        return update(date, -1, -1, -1, hour, minute, second, -1);
    }

    /**
     * 更改指定时间的"年/月/日/时/分/秒/毫秒"
     * <br> 说明：<font color="red">如值为-1则不进行修改</font>
     *
     * @param date        原始时间
     * @param year        年
     * @param month       月
     * @param day         日
     * @param hour        时
     * @param minute      分
     * @param second      秒
     * @param milliSecond 毫秒
     * @return
     */
    public static Date update(Date date, int year, int month, int day, int hour, int minute,
                              int second, int milliSecond) {

        if (date == null) {
            return null;
        }

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);

        if (year != -1)
            calendar.set(Calendar.YEAR, year);
        if (month != -1)
            calendar.set(Calendar.MONTH, month - 1);
        if (day != -1)
            calendar.set(Calendar.DATE, day);
        if (hour != -1)
            calendar.set(Calendar.HOUR_OF_DAY, hour);
        if (minute != -1)
            calendar.set(Calendar.MINUTE, minute);
        if (second != -1)
            calendar.set(Calendar.SECOND, second);
        if (milliSecond != -1)
            calendar.set(Calendar.MILLISECOND, milliSecond);

        return calendar.getTime();
    }

    public static Date getBeforeDate(Date date, int beforeDay) {
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);
        calendar.add(calendar.DATE, beforeDay);//把日期往后增加一天.整数往后推,负数往前移动
        Date endTime = calendar.getTime(); //这个时间就是日期往后推一天的结果
        return endTime;
    }

    public static final int dateSub(Date a, Date b) {

        int date = (int) (a.getTime() / (24 * 60 * 60 * 1000) - b.getTime() / (24 * 60 * 60 * 1000));

        return date <= 0 ? 0 : date;

    }

    /**
     * 判断时间是不是今天
     *
     * @param date
     * @return 是返回true，不是返回false
     */
    public static boolean isNow(Date date) {
        //当前时间
        Date now = new Date();
        SimpleDateFormat sf = new SimpleDateFormat("yyyyMMdd");
        //获取今天的日期
        String nowDay = sf.format(now);

        //对比的时间
        String day = sf.format(date);

        return day.equals(nowDay);
    }

    /**
     * 一天的开始时间
     *
     * @param date
     * @return
     */

    public static final Date dateBegin(Date date) {

        if (date == null)

            return null;

        Calendar calendar = Calendar.getInstance();

        calendar.setTime(date);

        dateBegin(calendar);

        return calendar.getTime();

    }

    /**
     * 一天的开始时间
     *
     * @param dateStr
     * @return
     */

    public static final Date dateBegin(String dateStr) {

        Date date = s2d(dateStr, DateUtil.defaultPattern);

        if (date == null)

            return null;

        Calendar calendar = Calendar.getInstance();

        calendar.setTime(date);

        dateBegin(calendar);

        return calendar.getTime();

    }

    /**
     * 一天的结束时间
     *
     * @param dateStr
     * @return
     */

    public static final Date dateEnd(String dateStr) {

        Date date = s2d(dateStr, DateUtil.defaultPattern);

        if (date == null)

            return null;

        Calendar calendar = Calendar.getInstance();

        calendar.setTime(date);

        dateEnd(calendar);

        return calendar.getTime();

    }

    /**
     * 一天的结束时间
     *
     * @param date
     * @return
     */

    public static final Date dateEnd(Date date) {

        if (date == null)

            return null;

        Calendar calendar = Calendar.getInstance();

        calendar.setTime(date);

        dateEnd(calendar);

        return calendar.getTime();

    }

    /**
     * 一天的结束时间
     *
     * @param calendar
     * @return
     */

    public static final Calendar dateEnd(Calendar calendar) {

        if (calendar == null)

            return null;

        calendar.set(Calendar.HOUR_OF_DAY, 23);

        calendar.set(Calendar.MINUTE, 59);

        calendar.set(Calendar.SECOND, 59);

        calendar.set(Calendar.MILLISECOND, 0);

        return calendar;

    }

    /**
     * 一天的开始时间
     *
     * @param calendar
     * @return
     */

    public static final Calendar dateBegin(Calendar calendar) {

        if (calendar == null)

            return null;

        calendar.set(Calendar.HOUR_OF_DAY, 0);

        calendar.set(Calendar.MINUTE, 0);

        calendar.set(Calendar.SECOND, 0);

        calendar.set(Calendar.MILLISECOND, 0);

        return calendar;

    }

    /**
     * 一月的开始时间
     *
     * @param date
     * @return
     */

    public static final Date monthBegin(Date date) {

        if (date == null)

            return null;

        Calendar calendar = Calendar.getInstance();

        calendar.setTime(date);

        int day = calendar.getActualMinimum(Calendar.DAY_OF_MONTH);

        calendar.set(Calendar.DATE, day);

        dateBegin(calendar);

        return calendar.getTime();

    }

    /**
     * 一月的技术时间
     *
     * @param date
     * @return
     */

    public static final Date monthEnd(Date date) {

        if (date == null)

            return null;

        Calendar calendar = Calendar.getInstance();

        calendar.setTime(date);

        int day = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);

        calendar.set(Calendar.DATE, day);

        dateEnd(calendar);

        return calendar.getTime();

    }

    /**
     * 一年的开始时间
     *
     * @param date
     * @return
     */

    public static Date yearBegin(Date date) {

        if (date == null)

            return null;

        Calendar calendar = Calendar.getInstance();

        calendar.setTime(date);

        calendar.set(Calendar.MONTH, 0);

        calendar.set(Calendar.DATE, 1);

        dateBegin(calendar);

        return calendar.getTime();

    }

    /**
     * 一年的结束时间
     *
     * @param date
     * @return
     */

    public static final Date yearEnd(Date date) {

        if (date == null)

            return null;

        Calendar calendar = Calendar.getInstance();

        calendar.setTime(date);

        calendar.set(Calendar.MONTH, 11);

        calendar.set(Calendar.DATE, 31);

        dateEnd(calendar);

        return calendar.getTime();

    }


    /**
     * 获取整点时间
     *
     * @param date
     * @return
     */

    public static final Date getDateByHour(Date date, int hour) {
        return getDateByMinute(date, hour, 0);
    }

    /**
     * 获取时间
     *
     * @param date
     * @return
     */
    public static final Date getDateByMinute(Date date, int hour, int minute) {
        Calendar calendar = Calendar.getInstance();

        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, hour);
        calendar.set(Calendar.MINUTE, minute);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    public static LocalDate timestampToDate(Long timestamp) {
        try {
            return Instant.ofEpochSecond(timestamp).atZone(ZoneOffset.ofHours(8)).toLocalDate();
        } catch (Exception e) {
            logger.info("timestamp转Date失败");
        }
        return null;
    }


    /**
     * 将 Date 转换成LocalDateTime
     * atZone()方法返回在指定时区从此Instant生成的ZonedDateTime。
     *
     * @param date
     * @return
     */
    public static LocalDateTime dateToLocalDateTime(Date date) {
        Instant instant = date.toInstant();
        ZoneId zoneId = ZoneId.of("GMT+8");
        return instant.atZone(zoneId).toLocalDateTime();
    }

    /**
     * 将 Date 转换成LocalDate
     * atZone()方法返回在指定时区从此Instant生成的ZonedDateTime。
     *
     * @param date
     * @return
     */
    public static LocalDate dateToLocalDate(Date date) {
        Instant instant = date.toInstant();
        ZoneId zoneId = ZoneId.of("GMT+8");
        return instant.atZone(zoneId).toLocalDate();
    }


    /**
     * LocalDate转Date
     *
     * @param localDate
     * @return
     */
    public static Date localDateToDate(LocalDate localDate) {
        ZoneId zone = ZoneId.systemDefault();
        Instant instant = localDate.atStartOfDay().atZone(zone).toInstant();
        Date date = Date.from(instant);
        return date;
    }

    /**
     * localDate 转string
     *
     * @param localDate
     * @return
     */
    public static String LocalDateToString(LocalDate localDate) {
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        String dateStr = localDate.format(fmt);
        return dateStr;
    }

    /**
     * string转localdate
     *
     * @param dateStr
     * @return
     */
    public static LocalDate stringToLocalDate(String dateStr) {
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate date = LocalDate.parse(dateStr, fmt);
        return date;
    }

    public static LocalDateTime stringToLocalDateTime(String date) {
        return LocalDateTime.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
    }

    /**
     * @param date
     * @param type 0 ；1
     * @return
     * @throws ParseException
     */
    public static Date stringToDate(String date, Integer type) throws ParseException {
        Assert.notNull(type, "type不能为空！");
        if (type == 0) {
            return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(date);
        } else {
            return new SimpleDateFormat("yyyy-MM-dd").parse(date);
        }

    }

    /**
     * 根据当前周号，计算n周前或后的周一日期
     *
     * @param year
     * @param week
     * @param targetNum
     * @return
     */
    public static String getWeekDays(int year, int week, int targetNum) {
        // 计算目标周数
        if (week + targetNum > 52) {
            year++;
        } else if (week + targetNum <= 0) {
            year--;
            week += targetNum + 52;
        } else {
            week += targetNum;
        }

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cal = Calendar.getInstance();

        // 设置每周的开始日期
        cal.setFirstDayOfWeek(Calendar.MONDAY);

        cal.set(Calendar.YEAR, year);
        cal.set(Calendar.WEEK_OF_YEAR, week);
        cal.set(Calendar.DAY_OF_WEEK, cal.getFirstDayOfWeek());

        // 该周周一
        String beginDate = sdf.format(cal.getTime());

        cal.add(Calendar.DAY_OF_WEEK, 6);
        // 该周周日
        String endDate = sdf.format(cal.getTime());

        return beginDate;
    }

    /**
     * 根据年，周号，获取该周周日
     *
     * @return
     */
    public static LocalDate getDateByYearAndWeekNo(int year, int week) {
        WeekFields weekFields2 = WeekFields.of(DayOfWeek.MONDAY, 4);
        LocalDate sunday = LocalDate.now()
                .withYear(year)
                .with(weekFields2.weekOfYear(), week)
                .with(weekFields2.dayOfWeek(), 7L);

        return sunday;
    }

    /**
     * 日期加、减几月
     *
     * @param str
     * @param amount 正数加，负数减
     * @return
     * @throws Exception
     */
    public static String dateMinusMonth(String str, int amount) throws Exception {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM");
        Date dt = sdf.parse(str);//将字符串生成Date
        Calendar rightNow = Calendar.getInstance();
        rightNow.setTime(dt);//使用给定的 Date 设置此 Calendar 的时间。
        rightNow.add(Calendar.MONTH, amount);// 日期减1个月
        Date dt1 = rightNow.getTime();//返回一个表示此 Calendar 时间值的 Date 对象。
        String reStr = sdf.format(dt1);//将给定的 Date 格式化为日期/时间字符串，并将结果添加到给定的 StringBuffer。
        return reStr;
    }

    /**
     * 获取某个月最后一天
     *
     * @param datadate
     * @return
     * @throws Exception
     */
    public static String getLastDay(String datadate) throws Exception {
        Date date = null;
        String day_last = null;
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        date = format.parse(datadate);

//创建日历
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, 1); //加一个月
        calendar.set(Calendar.DATE, 1);//设置为该月第一天
        calendar.add(Calendar.DATE, -1);//再减一天即为上个月最后一天
        day_last = format.format(calendar.getTime());
        return day_last;
    }

    /**
     * 获取时间段内，所有天
     *
     * @param dBegin
     * @param dEnd
     * @return
     * @throws ParseException
     */
    public static List<String> findDates(String dBegin, String dEnd) throws ParseException {
        //日期工具类准备
        DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        //设置开始时间
        Calendar calBegin = Calendar.getInstance();
        calBegin.setTime(format.parse(dBegin));
        //设置结束时间
        Calendar calEnd = Calendar.getInstance();
        calEnd.setTime(format.parse(dEnd));
        //装返回的日期集合容器
        List<String> datelist = new ArrayList<String>();
        // 每次循环给calBegin日期加一天，直到calBegin.getTime()时间等于dEnd
        while (format.parse(dEnd).after(calBegin.getTime())) {
            // 根据日历的规则，为给定的日历字段添加或减去指定的时间量
            calBegin.add(Calendar.DAY_OF_MONTH, 1);
            datelist.add(format.format(calBegin.getTime()));
        }
        return datelist;
    }

    /**
     * 获取一段时间内，所有月份
     *
     * @param minDate
     * @param maxDate
     * @return
     * @throws ParseException
     */
    public static List<String> getMonthBetween(String minDate, String maxDate) throws ParseException {
        ArrayList<String> result = new ArrayList<String>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");//格式化为年月

        Calendar min = Calendar.getInstance();
        Calendar max = Calendar.getInstance();

        min.setTime(sdf.parse(minDate));
        min.set(min.get(Calendar.YEAR), min.get(Calendar.MONTH), 1);

        max.setTime(sdf.parse(maxDate));
        max.set(max.get(Calendar.YEAR), max.get(Calendar.MONTH), 2);

        Calendar curr = min;
        while (curr.before(max)) {
            result.add(sdf.format(curr.getTime()));
            curr.add(Calendar.MONTH, 1);
        }

        return result;
    }

    //n天前/后的时间 days +-
    public static Date getNDaysAgo(int days) {
        Calendar calendar1 = Calendar.getInstance();
        calendar1.add(Calendar.DATE, days);
        return calendar1.getTime();
    }



    /**
     * 获取明天的日期字符串
     *
     * @return
     */
    public static String getTomorrowStr() {
        DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String dateStr = sdf.format(new Date());
        Date date = null;
        Calendar calendar = Calendar.getInstance();
        try {
            date = sdf.parse(dateStr);
            calendar.setTime(date);
            calendar.add(Calendar.DAY_OF_MONTH, 1);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return sdf.format(calendar.getTime());
    }

    /**
     * 计算相差秒数
     * @param startDate
     * @return
     */
    public static int calLastedTime(Date startDate,Date endDate) {
        long a = endDate.getTime();
        long b = startDate.getTime();
        int c = (int)((a - b) / 1000);return c;
    }

    // 获得本周一0点时间
    public static Date getTimesWeekmorning() {
        Calendar cal = Calendar.getInstance();
        cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONDAY), cal.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
        cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        return cal.getTime();
    }

    // 获得本周日24点时间
    public static Date getTimesWeeknight() {
        Calendar cal = Calendar.getInstance();
        cal.setTime(getTimesWeekmorning());
        cal.add(Calendar.DAY_OF_WEEK, 7);
        return cal.getTime();
    }

    public static List<String> getDays(String startTime, String endTime) {

        // 返回的日期集合
        List<String> days = new ArrayList<String>();

        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        try {
            Date start = dateFormat.parse(startTime);
            Date end = dateFormat.parse(endTime);

            Calendar tempStart = Calendar.getInstance();
            tempStart.setTime(start);

            Calendar tempEnd = Calendar.getInstance();
            tempEnd.setTime(end);
            tempEnd.add(Calendar.DATE, +1);// 日期加1(包含结束)
            while (tempStart.before(tempEnd)) {
                days.add(dateFormat.format(tempStart.getTime()));
                tempStart.add(Calendar.DAY_OF_YEAR, 1);
            }

        } catch (ParseException e) {
            e.printStackTrace();
        }

        return days;
    }

    public static List<String> getDays(Date startTime, int n) {

        // 返回的日期集合
        List<String> days = new ArrayList<String>();

        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

        Calendar tempStart = Calendar.getInstance();
        tempStart.setTime(startTime);

        if(n > 0){
            for (int i = 0; i < n; i++) {
                tempStart.add(Calendar.DATE, i);// 日期加
                days.add(dateFormat.format(tempStart.getTime()));
                tempStart.setTime(startTime);
            }
        }

        if(n < 0){
            for (int i = 0; i > n; i--) {
                tempStart.add(Calendar.DATE, i);// 日期减
                days.add(dateFormat.format(tempStart.getTime()));
                tempStart.setTime(startTime);
            }
            Collections.reverse(days);
        }

        return days;
    }






    public static boolean belongCalendar(Date nowTime, Date beginTime, Date endTime) {
        Calendar date = Calendar.getInstance();
        date.setTime(nowTime);

        Calendar begin = Calendar.getInstance();
        begin.setTime(beginTime);

        Calendar end = Calendar.getInstance();
        end.setTime(endTime);

        return date.after(begin) && date.before(end);
    }

    public static Date timeAddDate(Date time, Date date) {
        Calendar timeC = Calendar.getInstance();
        timeC.setTime(time);

        Calendar dateC = Calendar.getInstance();
        dateC.setTime(date);

        timeC.set(Calendar.YEAR, dateC.get(Calendar.YEAR));
        timeC.set(Calendar.MONTH, dateC.get(Calendar.MONTH));
        timeC.set(Calendar.DATE, dateC.get(Calendar.DATE));

        return timeC.getTime();
    }

    public static Date zoneTimeToDate(String zoneTime){
        return s2d(zoneTime, ZONETIME);
    }

    /**
     * 日期型字符串转化为日期 格式
     */
    public static Date parseDate(Object str)
    {
        if (str == null)
        {
            return null;
        }
        try
        {
            return parseDate(str.toString(), parsePatterns);
        }
        catch (ParseException e)
        {
            return null;
        }
    }

    public static final String parseDateToStr(final String format, final Date date)
    {
        return new SimpleDateFormat(format).format(date);
    }


    /**
     * 时间戳处理方法
     */

    /**
     * 返回当前时间的秒数
     *
     * @return
     */
    public static int unixTime() {
        return (int) (System.currentTimeMillis() / 1000);
    }

    /**
     * 把秒转换为Date
     *
     * @param seconds
     * @return
     */
    public static Date fromUnixTime(Integer seconds) {
        return new Date(seconds * 1000L);
    }

    public static Date fromUnixTime(Long seconds) {
        return new Date(seconds * 1000L);
    }

    /**
     * 计算2个日期之间相差的  相差多少年
     * 比如：2011-02-02 到  2017-03-02 相差 6年
     * @param fromDate
     * @param toDate
     * @return
     */
    public static int dateCompareYear(Date fromDate,Date toDate){
        Calendar  from  =  Calendar.getInstance();
        from.setTime(fromDate);
        Calendar  to  =  Calendar.getInstance();
        to.setTime(toDate);
        int fromYear = from.get(Calendar.YEAR);
        int toYear = to.get(Calendar.YEAR);
        return toYear - fromYear;
    }

    /**
     * 计算2个日期之间相差的  相差多少年月日
     * 比如：2011-02-02 到  2017-03-02 相差 6年，1个月，0天
     * @param fromDate
     * @param toDate
     * @return
     */
    public static int dateCompareMonth(Date fromDate,Date toDate){
        Calendar  from  =  Calendar.getInstance();
        from.setTime(fromDate);
        Calendar  to  =  Calendar.getInstance();
        to.setTime(toDate);
        int fromMonth = from.get(Calendar.MONTH);
        int toMonth = to.get(Calendar.MONTH);
        return toMonth  - fromMonth;
    }

    /**
     * 计算2个日期之间相差的  相差多少年月日
     * 比如：2011-02-02 到  2017-03-02 相差 6年，1个月，0天
     * @param fromDate
     * @param toDate
     * @return
     */
    public static int dateCompareDay(Date fromDate,Date toDate){
        Calendar  from  =  Calendar.getInstance();
        from.setTime(fromDate);
        Calendar  to  =  Calendar.getInstance();
        to.setTime(toDate);
        int fromDay = from.get(Calendar.DAY_OF_MONTH);
        int toDay = to.get(Calendar.DAY_OF_MONTH);
        return toDay  - fromDay;
    }

    /**
     * 秒转分钟
     * @param seconds
     * @return
     */
    public static String s2m(Integer seconds){
        String mSec = "00";
        String mMin = "00";
        // 秒数
        int sec = seconds % 60;
        // 分钟数
        int min = (seconds - sec) / 60;
        // 如果秒数没超过10就在他前面加个0
        if (sec < 10) {
            mSec = "0" + sec;
        } else {
            mSec = String.valueOf(sec);
        }
        // 如果分钟数没超过10就在他前面加个0
        if (min < 10) {
            mMin = "0" + min;
        } else {
            mMin = String.valueOf(min);
        }
        return mMin+"分"+mSec+"秒";
    }

    /**
     * 将Date格式切割为时分秒
     */
    public static String dateToStrTime(Date date) {
        // 转换为 LocalDateTime
        LocalDateTime localDateTime = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();

        // 然后按上述方式提取时分秒
        int hour = localDateTime.getHour();
        int minute = localDateTime.getMinute();
        int second = localDateTime.getSecond();

        return hour + ":" + minute + ":" + second;
    }
    /**
     * 计算两个时间的时间差
     */
    public static Duration durationBetWeen(LocalDateTime startDate, LocalDateTime endDate) {

        // 计算每个时间段的时间差
        Duration difference1 = Duration.between(startDate, endDate);

        return difference1.plus(difference1);
    }
    /**
     * Date转LocalDateTime(使用上海时间)
     */
    public static LocalDateTime DateToLocal(Date date){

        Instant instant = date.toInstant();
        ZoneId targetZone = ZoneId.of("Asia/Shanghai");
        return instant.atZone(targetZone).toLocalDateTime();
    }

    public static Date getLastYearStartTime() {
        Calendar c = Calendar.getInstance();
        c.add(Calendar.YEAR, -1);
        c.set(Calendar.MONTH, 1);
        c.set(Calendar.DAY_OF_MONTH, 1);
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        return c.getTime();
    }

    public static Date getLastYearEndTime() {
        Calendar c = Calendar.getInstance();
        c.set(Calendar.MONTH, 1);
        c.set(Calendar.DAY_OF_MONTH, 1);
        c.add(Calendar.DATE, -1);
        c.set(Calendar.HOUR_OF_DAY, 23);
        c.set(Calendar.MINUTE, 59);
        c.set(Calendar.SECOND, 59);
        return c.getTime();
    }
}
